import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;

import javax.swing.tree.TreeNode;

/*
 * @lc app=leetcode.cn id=112 lang=java
 *
 * [112] 路径总和
 *
 * https://leetcode-cn.com/problems/path-sum/description/
 *
 * algorithms
 * Easy (52.76%)
 * Likes:    761
 * Dislikes: 0
 * Total Accepted:    309K
 * Total Submissions: 585.3K
 * Testcase Example:  '[5,4,8,11,null,13,4,7,2,null,null,null,1]\n22'
 *
 * 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点
 * 的路径，这条路径上所有节点值相加等于目标和 targetSum 。如果存在，返回 true ；否则，返回 false 。
 * 
 * 叶子节点 是指没有子节点的节点。
 * 
 * 
 * 
 * 示例 1：
 * 
 * 
 * 输入：root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
 * 输出：true
 * 解释：等于目标和的根节点到叶节点路径如上图所示。
 * 
 * 
 * 示例 2：
 * 
 * 
 * 输入：root = [1,2,3], targetSum = 5
 * 输出：false
 * 解释：树中存在两条根节点到叶子节点的路径：
 * (1 --> 2): 和为 3
 * (1 --> 3): 和为 4
 * 不存在 sum = 5 的根节点到叶子节点的路径。
 * 
 * 示例 3：
 * 
 * 
 * 输入：root = [], targetSum = 0
 * 输出：false
 * 解释：由于树是空的，所以不存在根节点到叶子节点的路径。
 * 
 * 
 * 
 * 
 * 提示：
 * 
 * 
 * 树中节点的数目在范围 [0, 5000] 内
 * -1000 <= Node.val <= 1000
 * -1000 <= targetSum <= 1000
 * 
 * 
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {

    // 深度优先
    // public boolean hasPathSum(TreeNode root, int targetSum) {
    //     if (root == null) {
    //         return false;
    //     }
    //     boolean ret = false;
    //     Stack<TreeNode> stack = new Stack<>();
    //     Set<TreeNode> visited = new HashSet<>();
    //     stack.push(root);
    //     int trace = root.val;
    //     while (!stack.isEmpty()) {
    //         TreeNode treeNode = stack.peek();
    //         if (trace == targetSum && treeNode.left == null && treeNode.right == null) {
    //             ret = true;
    //             break;
    //         } else if (treeNode.left != null && !visited.contains(treeNode.left)) {
    //             stack.push(treeNode.left);
    //             visited.add(treeNode.left);
    //             trace += treeNode.left.val;
    //         } else if (treeNode.right != null && !visited.contains(treeNode.right)) {
    //             stack.push(treeNode.right);
    //             visited.add(treeNode.right);
    //             trace += treeNode.right.val;
    //         } else {
    //             trace -= stack.pop().val;
    //         }
    //     }
    //     return ret;
    // }

    // 广度优先
    // public boolean hasPathSum(TreeNode root, int targetSum) {
    //     if (root == null) {
    //         return false;
    //     }
    //     Queue<TreeNode> queue = new LinkedList<>();
    //     queue.offer(root);
    //     boolean ret = false;
    //     mark:
    //     while (!queue.isEmpty()) {
    //         int cnt = queue.size();
    //         for (int i = 0; i < cnt; i++) {
    //             TreeNode treeNode = queue.poll();
    //             if (treeNode.left == null && treeNode.right == null && treeNode.val == targetSum) {
    //                 ret = true; break mark;
    //             }
    //             if (treeNode.left != null) {
    //                 // 将路径值存在节点中
    //                 treeNode.left.val += treeNode.val;
    //                 queue.offer(treeNode.left);
    //             }
    //             if (treeNode.right != null) {
    //                 treeNode.right.val += treeNode.val;
    //                 queue.offer(treeNode.right);
    //             }
    //         }
    //     }
    //     return ret;
    // }

    // 递归
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) return false;
        if (root.left == null && root.right == null && root.val == targetSum) return true;
        return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
    }

}
// @lc code=end

